/******************************************************************************
 * @file    Charlieplexing_hal.c
 * @author  赵子恒 3393018959@qq.com 公众号：子恒笔记
 * @version V1.0
 * @date    2025-05-06
 * @brief   Charlieplexing HAL implementation for PY32F030xx.
 ******************************************************************************
 ******************************************************************************
 */
#ifndef __CHARLIEPLEXING_HAL_H
#define __CHARLIEPLEXING_HAL_H

#include "stdint.h"
#include "string.h"

#include "py32f0xx_ll_gpio.h"
#include "py32f0xx_ll_bus.h"

#ifndef countof
#define countof(a) (sizeof(a) / sizeof(*(a)))
#endif

//打开所有用到的gpio时钟
#define HAL_CHARLIEPLEXING_ALL_CLK_EN() do{\
	LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA);\
	LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOB);\
}while(0)

//对charli用到的所有GPIO编号
typedef enum
{
  HAL_GPIO_ID_L0 = 0x00,
  HAL_GPIO_ID_L1,
  HAL_GPIO_ID_L2,
  HAL_GPIO_ID_L3,
  HAL_GPIO_ID_L4,
  HAL_GPIO_ID_L5,
  HAL_GPIO_ID_MAX,
} hal_gpio_id_t;

//对charli用到的所有LED编号
typedef enum
{
  HAL_LED_ID_0 = 0x00,
  HAL_LED_ID_1,
  HAL_LED_ID_2,
  HAL_LED_ID_3,
  HAL_LED_ID_4,
  HAL_LED_ID_5,
  HAL_LED_ID_6,
  HAL_LED_ID_7,
  HAL_LED_ID_8,
  HAL_LED_ID_9,
  HAL_LED_ID_10,
  HAL_LED_ID_11,
  HAL_LED_ID_12,
  HAL_LED_ID_13,
  HAL_LED_ID_14,
  HAL_LED_ID_15,
  HAL_LED_ID_16,
  HAL_LED_ID_17,
  HAL_LED_ID_18,
  HAL_LED_ID_19,
  HAL_LED_ID_20,
  HAL_LED_ID_21,
  HAL_LED_ID_22,
  HAL_LED_ID_23,
  HAL_LED_ID_24,
  HAL_LED_ID_25,
  HAL_LED_ID_26,
  HAL_LED_ID_27,
  HAL_LED_ID_28,
  HAL_LED_ID_29,
  HAL_LED_ID_MAX
} hal_led_id_t;

//对charli用到的所有GPIO进行关系绑定
#define HAL_GPIO_MAP { \
    [HAL_GPIO_ID_L0] = {GPIOB, LL_GPIO_PIN_2},\
    [HAL_GPIO_ID_L1] = {GPIOA, LL_GPIO_PIN_9},\
    [HAL_GPIO_ID_L2] = {GPIOA, LL_GPIO_PIN_10},\
    [HAL_GPIO_ID_L3] = {GPIOA, LL_GPIO_PIN_12},\
    [HAL_GPIO_ID_L4] = {GPIOA, LL_GPIO_PIN_11},\
    [HAL_GPIO_ID_L5] = {GPIOB, LL_GPIO_PIN_5} \
}

//对charli用到的所有LED进行关系绑定，即给出这个LED阳极连接的pin，阴极连接的pin
#define HAL_ID_MAP { \
	[HAL_LED_ID_0]  = {HAL_GPIO_ID_L0, HAL_GPIO_ID_L1},\
	[HAL_LED_ID_1]  = {HAL_GPIO_ID_L0, HAL_GPIO_ID_L2},\
	[HAL_LED_ID_2]  = {HAL_GPIO_ID_L0, HAL_GPIO_ID_L3},\
	[HAL_LED_ID_3]  = {HAL_GPIO_ID_L0, HAL_GPIO_ID_L4},\
	[HAL_LED_ID_4]  = {HAL_GPIO_ID_L0, HAL_GPIO_ID_L5},\
	[HAL_LED_ID_5]  = {HAL_GPIO_ID_L1, HAL_GPIO_ID_L0},\
	[HAL_LED_ID_6]  = {HAL_GPIO_ID_L1, HAL_GPIO_ID_L2},\
	[HAL_LED_ID_7]  = {HAL_GPIO_ID_L1, HAL_GPIO_ID_L3},\
	[HAL_LED_ID_8]  = {HAL_GPIO_ID_L1, HAL_GPIO_ID_L4},\
	[HAL_LED_ID_9]  = {HAL_GPIO_ID_L1, HAL_GPIO_ID_L5},\
	[HAL_LED_ID_10] = {HAL_GPIO_ID_L2, HAL_GPIO_ID_L0},\
	[HAL_LED_ID_11] = {HAL_GPIO_ID_L2, HAL_GPIO_ID_L1},\
	[HAL_LED_ID_12] = {HAL_GPIO_ID_L2, HAL_GPIO_ID_L3},\
	[HAL_LED_ID_13] = {HAL_GPIO_ID_L2, HAL_GPIO_ID_L4},\
	[HAL_LED_ID_14] = {HAL_GPIO_ID_L2, HAL_GPIO_ID_L5},\
	[HAL_LED_ID_15] = {HAL_GPIO_ID_L3, HAL_GPIO_ID_L0},\
	[HAL_LED_ID_16] = {HAL_GPIO_ID_L3, HAL_GPIO_ID_L1},\
	[HAL_LED_ID_17] = {HAL_GPIO_ID_L3, HAL_GPIO_ID_L2},\
	[HAL_LED_ID_18] = {HAL_GPIO_ID_L3, HAL_GPIO_ID_L4},\
	[HAL_LED_ID_19] = {HAL_GPIO_ID_L3, HAL_GPIO_ID_L5},\
	[HAL_LED_ID_20] = {HAL_GPIO_ID_L4, HAL_GPIO_ID_L0},\
	[HAL_LED_ID_21] = {HAL_GPIO_ID_L4, HAL_GPIO_ID_L1},\
	[HAL_LED_ID_22] = {HAL_GPIO_ID_L4, HAL_GPIO_ID_L2},\
	[HAL_LED_ID_23] = {HAL_GPIO_ID_L4, HAL_GPIO_ID_L3},\
	[HAL_LED_ID_24] = {HAL_GPIO_ID_L4, HAL_GPIO_ID_L5},\
	[HAL_LED_ID_25] = {HAL_GPIO_ID_L5, HAL_GPIO_ID_L0},\
	[HAL_LED_ID_26] = {HAL_GPIO_ID_L5, HAL_GPIO_ID_L1},\
	[HAL_LED_ID_27] = {HAL_GPIO_ID_L5, HAL_GPIO_ID_L2},\
	[HAL_LED_ID_28] = {HAL_GPIO_ID_L5, HAL_GPIO_ID_L3},\
	[HAL_LED_ID_29] = {HAL_GPIO_ID_L5, HAL_GPIO_ID_L4} \
}

typedef struct 
{
    GPIO_TypeDef *GPIOx;
    uint32_t Pin;
}hal_charlieplexing_gpio_map_t;

typedef struct
{
    hal_gpio_id_t gpio_high_id;
    hal_gpio_id_t gpio_low_id;
}hal_charlieplexing_id_map_t;

typedef enum
{
    HIGH_Z = 0,
    OUTPUT_0 = 1,
    OUTPUT_1 = 2,
}gpio_mode_enum_t;

typedef enum
{
    LED_OFF = 0,
    LED_ON
}led_mode_enum_t;

extern hal_charlieplexing_gpio_map_t gpio_map[];
extern hal_charlieplexing_id_map_t id_map[];

extern void hal_charlieplexing_init(void);
extern void hal_charlieplexing_gpio_all_highz(void);
extern void hal_charlieplexing_led_id_set(uint8_t led_id,led_mode_enum_t mode);
extern void hal_charlieplexing_gpio_id_set(hal_gpio_id_t gpio_id, gpio_mode_enum_t mode);
extern hal_gpio_id_t hal_find_com_low_gpio_id(hal_gpio_id_t gpio_low_id, uint8_t led_id);
extern hal_gpio_id_t hal_find_com_higt_gpio_id(hal_gpio_id_t gpio_higt_id, uint8_t led_id);
#endif




